﻿using JQ.ServiceManager.Base.Models;
using Microsoft.Win32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration.Install;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Reflection;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;

namespace JQ.ServiceManager.Base
{
    public class ServiceOperation
    {
        public static LogApi logger = new LogApi();

        public static IEnumerable<ServiceManagementObject> GetServiceInfoFromWMI(string servName)
        {
            string query = "";
            if(string.IsNullOrEmpty(servName))
            {
                query = $"SELECT * FROM Win32_Service";
            }
            else
            {
                query = $"SELECT * FROM Win32_Service Where DisplayName = '{servName}'";
            }

            string[] lvData = new string[6];
            List<ServiceManagementObject> smos = new List<ServiceManagementObject>();
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
            foreach (ManagementObject mo in searcher.Get())
            {
                ServiceManagementObject currSMO = new ServiceManagementObject();
                if(mo["Name"] != null && !string.IsNullOrEmpty(mo["Name"].ToString()))
                {
                    currSMO.Name = mo["Name"].ToString();
                }

                if (mo["DisplayName"] != null && !string.IsNullOrEmpty(mo["DisplayName"].ToString()))
                {
                    currSMO.DisplayName = mo["DisplayName"].ToString();
                }

                lvData[2] = mo["StartMode"].ToString();
                if (mo["StartMode"] != null && !string.IsNullOrEmpty(mo["StartMode"].ToString()))
                {
                    currSMO.StartMode = mo["StartMode"].ToString();
                }

                if(mo["Started"] != null)
                {
                    if (mo["Started"].Equals(true))
                    {
                        currSMO.Status = "Started";
                    }
                    else
                    {
                        currSMO.Status = "Stop";
                    }
                }

                if (mo["PathName"] != null && !string.IsNullOrEmpty(mo["PathName"].ToString()))
                {
                    currSMO.PathName = mo["PathName"].ToString().Replace("\"","");
                }

                if (mo["StartName"] != null && !string.IsNullOrEmpty(mo["StartName"].ToString()))
                {
                    currSMO.StartName = mo["StartName"].ToString();
                }

                yield return currSMO;
            }
        }

            /// <summary>
            /// 返回服务名等详细信息
            /// </summary>
            /// <param name="filePath"></param>
            /// <returns>服务名,展示名,描述</returns>
            public static Tuple<string, string,string> RetriveDetil(string filePath,out string error)
        {
            try
            {
                Assembly ass = Assembly.LoadFile(filePath);
                error = string.Empty;
                var types = ass.GetTypes();
                foreach (var item in types)
                {
                    if (item.GetTypeInfo().Name == "ProjectInstaller")
                    {
                        FieldInfo[] propinfos = item.GetFields();

                        var projectInstaller = (Installer)Activator.CreateInstance(item);
                        var installs = projectInstaller.Installers;
                        foreach (var inst in installs)
                        {
                            if (inst.GetType() == typeof(ServiceInstaller))
                            {
                                string serName = ((ServiceInstaller)inst).ServiceName;
                                string dispName = ((ServiceInstaller)inst).DisplayName;
                                string desc = ((ServiceInstaller)inst).Description;
                                return new Tuple<string, string, string>(serName, dispName, desc);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                error = ex.Message;
            }
            return null;
        }

        /// <summary>
        /// 指定服务是否存在
        /// </summary>
        /// <param name="NameService"></param>
        /// <returns></returns>
        public static bool isServiceIsExisted(string NameService)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController s in services)
            {
                if (s.ServiceName.ToLower() == NameService.ToLower())
                {
                    return true;
                }
            }
            return false;
        }

        public static void GetServiceStatus(ref List<JQ.ServiceManager.Base.Models.ServiceBase> servItem)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (var _serItem in servItem)
            {
                foreach (ServiceController s in services)
                {
                    if (s.ServiceName.ToLower() == _serItem.ServiceName.ToLower())
                    {
                        switch (s.Status)
                        {
                            case ServiceControllerStatus.Running:
                                _serItem.Status = "运行中";
                                break;
                            case ServiceControllerStatus.Stopped:
                                _serItem.Status = "停止";
                                break;
                            case ServiceControllerStatus.StopPending:
                                _serItem.Status = "正在停止";
                                break;
                            case ServiceControllerStatus.StartPending:
                                _serItem.Status = "正在启动";
                                break;
                            case ServiceControllerStatus.ContinuePending:
                                _serItem.Status = "即将继续";
                                break;
                            case ServiceControllerStatus.PausePending:
                                _serItem.Status = "即将暂停";
                                break;
                            case ServiceControllerStatus.Paused:
                                _serItem.Status = "暂停";
                                break;
                            default:
                                //_serItem.Status = "未知状态";
                                break;
                        }
                    }
                    else
                    {
                        //_serItem.Status = "未知状态";
                    }
                } 
            }
        }

        /// <summary>
        /// 安装服务
        /// </summary>
        /// <param name="stateSaver"></param>
        /// <param name="filepath"></param>
        public static void InstallService(IDictionary stateSaver, string filepath)
        {
            try
            {
                AssemblyInstaller AssemblyInstaller1 = new AssemblyInstaller();
                AssemblyInstaller1.UseNewContext = true;
                AssemblyInstaller1.Path = filepath;
                AssemblyInstaller1.Install(stateSaver);
                AssemblyInstaller1.Commit(stateSaver);
                AssemblyInstaller1.Dispose();
            }
            catch (Exception ex)
            {
                logger.Error($"安装服务异常！{ex.Message}",ex.StackTrace);
                throw;
            }
        }

        /// <summary>
        /// 卸载服务
        /// </summary>
        /// <param name="filepath"></param>
        public static void UnInstallService(string filepath)
        {
            try
            {
                AssemblyInstaller AssemblyInstaller1 = new AssemblyInstaller();
                AssemblyInstaller1.UseNewContext = true;
                AssemblyInstaller1.Path = filepath;
                AssemblyInstaller1.Uninstall(null);
                AssemblyInstaller1.Dispose();
            }
            catch (Exception ex)
            {
                logger.Error($"卸载服务异常！{ex.Message}", ex.StackTrace);
                throw;
            }
        }

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="NameService"></param>
        /// <returns></returns>
        public static bool RunService(string NameService)
        {
            bool bo = true;
            try
            {
                ServiceController sc = new ServiceController(NameService);
                if (sc.Status.Equals(ServiceControllerStatus.Stopped) || sc.Status.Equals(ServiceControllerStatus.StopPending))
                {
                    sc.Start();
                }
            }
            catch (Exception ex)
            {
                logger.Error($"运行服务异常！{ex.Message}", ex.StackTrace);
                bo = false;
            }

            return bo;
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="NameService"></param>
        /// <returns></returns>
        public static bool StopService(string NameService)
        {
            bool bo = true;
            try
            {
                ServiceController sc = new ServiceController(NameService);
                if (!sc.Status.Equals(ServiceControllerStatus.Stopped))
                {
                    sc.Stop();
                }
            }
            catch (Exception ex)
            {
                logger.Error($"停止服务异常！{ex.Message}", ex.StackTrace);
                bo = false;
            }

            return bo;
        }

        /// <summary>
        /// 获取服务状态
        /// </summary>
        /// <param name="NameService"></param>
        /// <returns></returns>
        public static int GetServiceStatus(string NameService)
        {
            int ret = 0;
            try
            {
                ServiceController sc = new ServiceController(NameService);
                ret = Convert.ToInt16(sc.Status);
            }
            catch (Exception ex)
            {
                logger.Error($"获取服务状态异常！{ex.Message}", ex.StackTrace);
                ret = 0;
            }
            return ret;
        }

        /// <summary>
        /// 获取服务安装路径
        /// </summary>
        /// <param name="ServiceName"></param>
        /// <returns></returns>
        public static string GetWindowsServiceInstallPath(string ServiceName)
        {
            string path = "";
            try
            {
                string key = @"SYSTEM\CurrentControlSet\Services\" + ServiceName;
                path = Registry.LocalMachine.OpenSubKey(key).GetValue("ImagePath").ToString();

                path = path.Replace("\"", string.Empty);//替换掉双引号    

                FileInfo fi = new FileInfo(path);
                path = fi.Directory.ToString();
            }
            catch (Exception ex)
            {
                logger.Error($"获取服务安装路径异常！{ex.Message}", ex.StackTrace);

                path = "";
            }
            return path;
        }

        public static string KillProcess(string processName)
        {
            foreach (var process in Process.GetProcesses())
            {
                try
                {
                    if (!string.IsNullOrEmpty(processName) && processName.Contains(process.ProcessName))
                    {
                        process.Kill();
                        process.WaitForExit();
                    }
                }
                catch (Exception ex)
                {
                    string msg = $"终止进程失败：{ex.Message}{Environment.NewLine}{ex.StackTrace}";
                    return msg;
                }
            }
            return string.Empty;
        }
    }
}
